package com.wl.springsecuritystudy.config;


import com.wl.springsecuritystudy.LoginAccountContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Optional;

/**
 * token的校验
 * <p>
 * <p>
 * 该类继承自BasicAuthenticationFilter，在doFilterInternal方法中，<br/>
 * 从http头的Authorization 项读取token数据，然后用Jwts包提供的方法校验token的合法性。<br/>
 * 如果校验通过，就认为这是一个取得授权的合法请求<br/>
 *
 */
@Slf4j
public class JwtAuthenticationFilter extends BasicAuthenticationFilter {


    public JwtAuthenticationFilter(AuthenticationManager authenticationManager,
                                   AuthenticationEntryPoint authenticationEntryPoint) {
        super(authenticationManager, authenticationEntryPoint);
    }

    @Override
    public void destroy() {
        super.destroy();
        log.info("摧毁Jwt Authentication Filter");
    }

    @Override
    protected void initFilterBean() throws ServletException {
        super.initFilterBean();
        log.info("初始化Jwt Authentication Filter");
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        // 开放平台需要对IP进行校验
        Optional<SessionInfo> openOpt = LoginAccountContext.currentSession();
        if (openOpt.isPresent()) {
            SessionInfo openUserInfo = openOpt.get();

        }

        String token = request.getHeader(ConstantJwt.TOKEN_HTTP_HEADER);
        if (StringUtils.isBlank(token)) {
            getAuthenticationEntryPoint().commence(request, response, new TokenException("令牌为空"));
            return;
        }
        log.debug("当前请求的令牌:{}", token);
        Optional<SessionInfo> requestSessionOpt = JwtUtil.parserJwt(token);
        if (requestSessionOpt.isPresent()) {
            getAuthenticationEntryPoint().commence(request, response, new TokenException("无效的令牌"));
            return;
        }
        SessionInfo sessionInfo = requestSessionOpt.get();


        // 把session设置到Security上下文中
        JwtAuthenticationToken authenticationToken = new JwtAuthenticationToken(sessionInfo.getUserId(), token, new ArrayList<>());
        authenticationToken.setSession(sessionInfo);
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);

        log.debug("当前请求的令牌校验通过");
        //
        chain.doFilter(request, response);
    }
}
